#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
数据库模型定义
包含账号、角色、挂机记录等数据模型
"""

from datetime import datetime, timedelta
from typing import Dict, Any, List, Optional
from dataclasses import dataclass
from enum import Enum
from src.character.experience_system import exp_system

class CharacterClass(Enum):
    """角色职业枚举"""
    WARRIOR = "战士"
    MAGE = "法师"
    ARCHER = "弓箭手"
    ASSASSIN = "刺客"
    PRIEST = "牧师"

class CharacterStatus(Enum):
    """角色状态枚举"""
    IDLE = "idle"  # 挂机中
    BATTLE = "battle"  # 战斗中
    OFFLINE = "offline"  # 离线

class BattleType(Enum):
    """战斗类型枚举"""
    PVP = "pvp"
    PVE = "pve"
    GUILD_WAR = "guild_war"

class BattleStatus(Enum):
    """战斗状态枚举"""
    WAITING = "waiting"
    IN_PROGRESS = "in_progress"
    COMPLETED = "completed"
    CANCELLED = "cancelled"

@dataclass
class Account:
    """账号模型"""
    account_id: Optional[int] = None
    username: str = ""
    email: str = ""
    password_hash: str = ""
    created_at: Optional[datetime] = None
    last_login: Optional[datetime] = None
    is_active: bool = True
    
    def to_dict(self) -> Dict[str, Any]:
        """转换为字典"""
        return {
            'account_id': self.account_id,
            'username': self.username,
            'email': self.email,
            'password_hash': self.password_hash,
            'created_at': self.created_at,
            'last_login': self.last_login,
            'is_active': self.is_active
        }
    
    @classmethod
    def from_dict(cls, data: Dict[str, Any]) -> 'Account':
        """从字典创建实例"""
        # 处理数据库中的 status 字段映射到 is_active
        is_active = data.get('is_active', True)
        if 'status' in data:
            is_active = data['status'] == 'active'
        
        # 处理数据库中的 id 字段映射到 account_id
        account_id = data.get('account_id') or data.get('id')
        
        return cls(
            account_id=account_id,
            username=data.get('username', ''),
            email=data.get('email', ''),
            password_hash=data.get('password_hash', ''),
            created_at=data.get('created_at'),
            last_login=data.get('last_login'),
            is_active=is_active
        )

@dataclass
class Character:
    """角色模型"""
    char_id: Optional[int] = None
    account_id: int = 0
    name: str = ""
    char_class: CharacterClass = CharacterClass.WARRIOR
    level: int = 1
    exp: int = 0
    hp: int = 100
    mp: int = 50
    attack: int = 10
    defense: int = 5
    speed: int = 8
    status: CharacterStatus = CharacterStatus.IDLE
    created_at: Optional[datetime] = None
    last_active: Optional[datetime] = None
    
    def to_dict(self) -> Dict[str, Any]:
        """转换为字典"""
        return {
            'char_id': self.char_id,
            'account_id': self.account_id,
            'name': self.name,
            'char_class': self.char_class.value if isinstance(self.char_class, CharacterClass) else self.char_class,
            'level': self.level,
            'exp': self.exp,
            'hp': self.hp,
            'mp': self.mp,
            'attack': self.attack,
            'defense': self.defense,
            'speed': self.speed,
            'status': self.status.value if isinstance(self.status, CharacterStatus) else self.status,
            'created_at': self.created_at,
            'last_active': self.last_active
        }
    
    @classmethod
    def from_dict(cls, data: Dict[str, Any]) -> 'Character':
        """从字典创建实例"""
        # 处理职业名称映射（英文到中文）
        char_class_value = data.get('character_class', '战士')
        class_mapping = {
            'warrior': '战士',
            'mage': '法师', 
            'archer': '弓箭手',
            'assassin': '刺客',
            'priest': '牧师',
            '盗贼': '刺客'  # 兼容性映射
        }
        
        # 如果是英文名，转换为中文名
        if char_class_value in class_mapping:
            char_class_value = class_mapping[char_class_value]
        
        return cls(
            char_id=data.get('id') or data.get('char_id'),  # 数据库使用 id，模型使用 char_id
            account_id=data.get('account_id', 0),
            name=data.get('name', ''),
            char_class=CharacterClass(char_class_value),  # 数据库使用 character_class
            level=data.get('level', 1),
            exp=data.get('exp', 0),
            hp=data.get('hp', 100),
            mp=data.get('mp', 50),
            attack=data.get('attack', 10),
            defense=data.get('defense', 5),
            speed=data.get('speed', 8),
            status=CharacterStatus(data.get('status', 'idle')),
            created_at=data.get('created_at'),
            last_active=data.get('last_active')
        )
    
    def get_exp_for_next_level(self) -> int:
        """获取升级所需经验"""
        from src.character.experience_system import exp_system
        level_info = exp_system.get_level_info(self.level)
        return level_info.exp_to_next_level
    
    def can_level_up(self) -> bool:
        """是否可以升级"""
        from src.character.experience_system import exp_system
        return exp_system.can_level_up(self.level, self.exp)
    
    def level_up(self) -> bool:
        """升级"""
        from src.character.experience_system import exp_system
        
        if not self.can_level_up():
            return False
        
        # 使用新的经验系统处理升级
        new_level, new_exp, levels_gained = exp_system.process_level_up(self.level, self.exp)
        
        # 计算属性提升
        levels_up = new_level - self.level
        if levels_up > 0:
            # 根据职业不同，属性提升也不同
            class_multipliers = self._get_class_attribute_multipliers()
            
            self.hp += int(20 * levels_up * class_multipliers['hp'])
            self.mp += int(10 * levels_up * class_multipliers['mp'])
            self.attack += int(2 * levels_up * class_multipliers['attack'])
            self.defense += int(1 * levels_up * class_multipliers['defense'])
            self.speed += int(1 * levels_up * class_multipliers['speed'])
            
            self.level = new_level
            self.exp = new_exp
            
            return True
        
        return False
    
    def _get_class_attribute_multipliers(self) -> Dict[str, float]:
        """获取职业属性成长倍率"""
        multipliers = {
            CharacterClass.WARRIOR: {
                'hp': 1.5, 'mp': 0.5, 'attack': 1.3, 'defense': 1.5, 'speed': 0.8
            },
            CharacterClass.MAGE: {
                'hp': 0.7, 'mp': 2.0, 'attack': 1.5, 'defense': 0.6, 'speed': 1.0
            },
            CharacterClass.ARCHER: {
                'hp': 1.0, 'mp': 1.0, 'attack': 1.4, 'defense': 0.8, 'speed': 1.6
            },
            CharacterClass.ASSASSIN: {
                'hp': 0.9, 'mp': 0.8, 'attack': 1.6, 'defense': 0.7, 'speed': 1.8
            }
        }
        return multipliers.get(self.char_class, multipliers[CharacterClass.WARRIOR])
    
    def get_exp_progress(self) -> Dict[str, any]:
        """获取经验进度信息"""
        from src.character.experience_system import exp_system
        return exp_system.get_exp_progress(self.level, self.exp)
    
    def add_exp(self, exp_amount: int) -> List[int]:
        """添加经验并处理升级
        
        Args:
            exp_amount: 要添加的经验值
            
        Returns:
            升级的等级列表
        """
        from src.character.experience_system import exp_system
        
        self.exp += exp_amount
        new_level, new_exp, levels_gained = exp_system.process_level_up(self.level, self.exp)
        
        if levels_gained:
            # 计算属性提升
            levels_up = len(levels_gained)
            class_multipliers = self._get_class_attribute_multipliers()
            
            self.hp += int(20 * levels_up * class_multipliers['hp'])
            self.mp += int(10 * levels_up * class_multipliers['mp'])
            self.attack += int(2 * levels_up * class_multipliers['attack'])
            self.defense += int(1 * levels_up * class_multipliers['defense'])
            self.speed += int(1 * levels_up * class_multipliers['speed'])
            
            self.level = new_level
            self.exp = new_exp
        
        return levels_gained

@dataclass
class IdleLocation:
    """挂机地点模型"""
    location_id: Optional[int] = None
    name: str = ""
    description: str = ""
    min_level: int = 1
    max_level: int = 100
    base_exp_rate: int = 100
    base_gold_rate: int = 50
    is_active: bool = True
    
    def to_dict(self) -> Dict[str, Any]:
        """转换为字典"""
        return {
            'location_id': self.location_id,
            'name': self.name,
            'description': self.description,
            'min_level': self.min_level,
            'max_level': self.max_level,
            'base_exp_rate': self.base_exp_rate,
            'base_gold_rate': self.base_gold_rate,
            'is_active': self.is_active
        }
    
    @classmethod
    def from_dict(cls, data: Dict[str, Any]) -> 'IdleLocation':
        """从字典创建实例"""
        return cls(
            location_id=data.get('location_id'),
            name=data.get('name', ''),
            description=data.get('description', ''),
            min_level=data.get('min_level', 1),
            max_level=data.get('max_level', 100),
            base_exp_rate=data.get('base_exp_rate', 100),
            base_gold_rate=data.get('base_gold_rate', 50),
            is_active=data.get('is_active', True)
        )

@dataclass
class IdleRecord:
    """挂机记录模型"""
    record_id: Optional[int] = None
    char_id: int = 0
    location_id: int = 0
    start_time: Optional[datetime] = None
    end_time: Optional[datetime] = None
    exp_gained: int = 0
    gold_gained: int = 0
    is_active: bool = True
    
    def to_dict(self) -> Dict[str, Any]:
        """转换为字典"""
        return {
            'record_id': self.record_id,
            'char_id': self.char_id,
            'location_id': self.location_id,
            'start_time': self.start_time,
            'end_time': self.end_time,
            'exp_gained': self.exp_gained,
            'gold_gained': self.gold_gained,
            'is_active': self.is_active
        }
    
    @classmethod
    def from_dict(cls, data: Dict[str, Any]) -> 'IdleRecord':
        """从字典创建实例"""
        return cls(
            record_id=data.get('record_id'),
            char_id=data.get('char_id', 0),
            location_id=data.get('location_id', 0),
            start_time=data.get('start_time'),
            end_time=data.get('end_time'),
            exp_gained=data.get('exp_gained', 0),
            gold_gained=data.get('gold_gained', 0),
            is_active=data.get('is_active', True)
        )
    
    def get_duration_hours(self) -> float:
        """获取挂机时长（小时）"""
        if not self.start_time:
            return 0.0
        
        end_time = self.end_time or datetime.now()
        duration = end_time - self.start_time
        return duration.total_seconds() / 3600
    
    def is_max_duration_reached(self, max_hours: int = 4) -> bool:
        """是否达到最大挂机时长"""
        return self.get_duration_hours() >= max_hours

@dataclass
class Battle:
    """战斗模型"""
    battle_id: Optional[int] = None
    battle_type: BattleType = BattleType.PVP
    status: BattleStatus = BattleStatus.WAITING
    created_by: int = 0
    created_at: Optional[datetime] = None
    started_at: Optional[datetime] = None
    ended_at: Optional[datetime] = None
    winner_team: Optional[int] = None
    battle_log: str = ""
    
    def to_dict(self) -> Dict[str, Any]:
        """转换为字典"""
        return {
            'battle_id': self.battle_id,
            'battle_type': self.battle_type.value if isinstance(self.battle_type, BattleType) else self.battle_type,
            'status': self.status.value if isinstance(self.status, BattleStatus) else self.status,
            'created_by': self.created_by,
            'created_at': self.created_at,
            'started_at': self.started_at,
            'ended_at': self.ended_at,
            'winner_team': self.winner_team,
            'battle_log': self.battle_log
        }
    
    @classmethod
    def from_dict(cls, data: Dict[str, Any]) -> 'Battle':
        """从字典创建实例"""
        return cls(
            battle_id=data.get('battle_id'),
            battle_type=BattleType(data.get('battle_type', 'pvp')),
            status=BattleStatus(data.get('status', 'waiting')),
            created_by=data.get('created_by', 0),
            created_at=data.get('created_at'),
            started_at=data.get('started_at'),
            ended_at=data.get('ended_at'),
            winner_team=data.get('winner_team'),
            battle_log=data.get('battle_log', '')
        )

@dataclass
class BattleParticipant:
    """战斗参与者模型"""
    participant_id: Optional[int] = None
    battle_id: int = 0
    char_id: int = 0
    team: int = 1
    joined_at: Optional[datetime] = None
    
    def to_dict(self) -> Dict[str, Any]:
        """转换为字典"""
        return {
            'participant_id': self.participant_id,
            'battle_id': self.battle_id,
            'char_id': self.char_id,
            'team': self.team,
            'joined_at': self.joined_at
        }
    
    @classmethod
    def from_dict(cls, data: Dict[str, Any]) -> 'BattleParticipant':
        """从字典创建实例"""
        return cls(
            participant_id=data.get('participant_id'),
            battle_id=data.get('battle_id', 0),
            char_id=data.get('char_id', 0),
            team=data.get('team', 1),
            joined_at=data.get('joined_at')
        )